package ar.edu.unq.home;

import java.util.List;

import org.hibernate.criterion.Criterion;

import ar.edu.unq.persistencia.HibernateManager;
import ar.edu.unq.persistencia.commands.CrearEntidadCommand;
import ar.edu.unq.persistencia.commands.DeleteCommand;
import ar.edu.unq.persistencia.commands.ObtenerEntidadCommand;

/**
 * TODO: description
 * 
 * @param <T>
 */
public abstract class Home<T> {

    private Class<T> clazz;

    public void setClazz(final Class<T> clazz) {
        this.clazz = clazz;
    }

    public Class<T> getClazz() {
        return this.clazz;
    }

    public List<T> findByCriterion(final List<Criterion> criterions) {
        ObtenerEntidadCommand<T> cmd = new ObtenerEntidadCommand<T>(this.getClazz());
        for (Criterion criterion : criterions) {
            cmd.addCriterion(criterion);
        }
        return this.execute(cmd);
    }

    public List<T> findByCriterion(final Criterion criterion) {
        ObtenerEntidadCommand<T> cmd = new ObtenerEntidadCommand<T>(this.getClazz());
        cmd.addCriterion(criterion);
        return this.execute(cmd);
    }

    private List<T> execute(final ObtenerEntidadCommand<T> cmd) {
        HibernateManager.instance().runInSessionWithOutTx(cmd);
        List<T> coll = cmd.getResult();
        return coll;
    }

    public T findEntity(final Criterion criterion) {
        return this.findByCriterion(criterion).get(0);
    }

    public List<T> getAllEntities() {
        ObtenerEntidadCommand<T> cmd = new ObtenerEntidadCommand<T>(this.getClazz());
        return this.execute(cmd);

    }

    public void saveOrUpdate(final T entity) {
        CrearEntidadCommand<T> cmd = new CrearEntidadCommand<T>(this.getClazz());
        cmd.getEntitiesToCreate().add(entity);
        HibernateManager.instance().runInSession(cmd);
    }

    public void delete(final T entity) {
        DeleteCommand<T> cmd = new DeleteCommand<T>(this.getClazz());
        cmd.getEntitiesToDelete().add(entity);
        HibernateManager.instance().runInSession(cmd);
    }

}
